<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="../css/reset.css">
    <script src="../js/vue.js"></script>
    <style>
        li {
            line-height: 40px;
            text-indent: 16px;
            border: 1px dashed #333;
            height: 40px;
        }
    </style>
</head>

<body>
    <div id="app">
        <p>
            <button @click="changeName">changeName</button>
            <button @click="changeAge">changeAge</button>
            <button @click="reset">reset</button>
            <button @click="addProp">addProp</button>
            <button @click="changeSex">changeSex</button>
        </p>
        <ul>
            <li>{{zhang.name}}</li>
            <li>{{zhang.age}}</li>
            <li>{{zhang.height}}</li>
            <li>{{zhang.weight}}</li>
            <li>{{zhang.sex}}</li>
        </ul>
    </div>
</body>
<script>

    // Vue 检测数组和对象的变化

    // Vue中 检测数据(data)中属性的变化,是依赖于数据劫持 Object.defineProperty()  => getter setter
    //     默认情况下,Vue是无法检测数组和对象的改变, 如果data中的属性对应的值是数组和对象时, 直接修改原数组/对象, data中该属性引入的地址没有改变 -> Vue是无法检测数组和对象的改变

    // 官方处理

    // 针对数组  => 数组更新检测   
    // 官方将数组的方法进行了分类: a. 影响原数组的方法 

    // 1. 变更方法(影响原数组的方法) => Vue 将被侦听的数组的变更方法进行了包裹，所以它们也将会触发视图更新
    // push unshift  pop shift splice reverse sort 

    // 2. 替换数组  => 非变更方法(不影响原数组的方法,而是返回新数组)  => 用新数组覆盖原本的数组  =>
    // concat()  slice()  map()  filter()  

    // 3. Vue无法检测数组以下变化
    //    list[0] = 100;
    //    list.length--;

    // 针对对象
    // 如果数据(data)上某个属性的值,也是一个对象 => 遍历该对象,给该对象上的每一个属性也绑定数据拦截  =>  无论是修改整个对象,还是修改对象上的某个属性,都会被Vue检测到 

    // Vue无法检测对象以下变化
    // 给对象新增属性   => Vue初始化渲染阶段,会给data中的属性,以及属性下的子对象绑定数据拦截,  新增的属性不会绑定 => Vue无法检测新增属性,和新增属性的变化

    // 注意: Vue对象数组和对象的检测默认是深层的!!!!!

    // !!! 不建议给data数据上新增属性 => 新增根属性 => 报错
    // Vue 不允许动态添加根级别的响应式 property

    // Object.defineProperty(data, "zhang", {
    //     get: function () { // 取值拦截
    //         console.log("data取值拦截",key);
    //         return defaultValue;
    //     },
    //     set: function (val) { // 赋值拦截
    //         console.log("data赋值拦截",key,val);
    //         defaultValue = val;

    //         render(); // 数据发生改变之后 -> 重新渲染
    //     }
    // })

    var app = new Vue({
        el: "#app",
        data: {
            // data上根属性
            list: [1, 4, 7, 2, 5, 8, 3, 6, 9],
            zhang: {
                name: "张三",
                age: 18,
                height: "173cm",
                weight: "70kg",
            },
            a: null,
        },
        methods: {
            changeName() {
                this.zhang.name = '李四'
            },
            changeAge() {
                this.zhang.age++;
            },
            reset() {
                this.zhang = {
                    name: "张三",
                    age: 18,
                    height: "173cm",
                    weight: "70kg",
                }
            },
            changeSex() {
                this.zhang.sex = this.zhang.sex == "男" ? "女" : "男";
                // this.$forceUpdate();
            },
            addProp() {
                // this.zhang.sex = "男";
                // console.log(this.zhang);

                // 强制更新视图  => 一次性操作
                // this.$forceUpdate();


                // 2. 使用Vue提供的 新增/修改数据的方法(对象)    => 没有就新增,有就修改
                //    Vue.set(data,key,val)    构造函数Vue的静态方法
                //    this.$set(data,key,val) 

                // Vue.set(this.zhang, "sex", "男");
                // console.log(this.zhang);


                Vue.set(this.$data, "a", 1)

            }
        }
    })
    console.log(app);


</script>

</html>